var hero;
var astarMap = [];

loadRes();

// --- ! INIT GAME FROM SERVER SECTION ! ---

    //charge la map envoyée par le srv
    function loadMap(sv_map,callback) {
        grid.width = sv_map.grid.width;
        grid.height = sv_map.grid.height;

        playerAreaBase = sv_map.playerAreaBase;
        playerRangeBase = sv_map.playerRangeBase;

        defaultTileWidth = sv_map.defaultTile.width;
        defaultTileHeight = sv_map.defaultTile.height;

//        console.log('loadMap() called...');

        loadTiles(sv_map);
    }
    //Charge toutes les tiles & leurs niveaux de santé
    function loadTiles(sv_map){
        for (var row = 0, i = 1; row < grid.width; row++) {
            tileMap[row] = [];

            for (var col = 0; col < grid.height; col++, i++) {
                var tilePositionX = (row - col) * defaultTileHeight;
                tilePositionX += (canvas.getWidth() / 2) - (defaultTileWidth / 2);
                var tilePositionY = (row + col) * (defaultTileHeight / 2);

                var curTile = sv_map.tiles[row][col];

                tileMap[row][col] = new Tile(
                    curTile.id,
                    curTile.heroId,
                    curTile.canPass,
                    curTile.humidity,
                    curTile.fertility, curTile.fertilityCap,
                    tilePositionX, tilePositionY);

                tileMap[row][col].updateHealthLevel();
            }
        }

//        console.log('loadTiles() called...');
    }

    function loadHerosData(sv_heros) {
        for(var i = 0; i < sv_heros.length; i++) {

            //Si on est sur le héros de l'account logged
            if(sv_heros[i].name == hero.name) {
                loadPlayerData(sv_heros[i]);
                continue;
            }

            //Sinon on instancie un autre héros avec ses tiles, crops & buildings
            var hEnemy = new Hero(sv_heros[i]._id, sv_heros[i].name, heroEnemy, sv_heros[i].gold);
            for(var t in sv_heros[i].tiles) {
                var tile = sv_heros[i].tiles[t];

                hEnemy.addTile(tile);
            }

            for(var c in sv_heros[i].crops) {
                var crop = sv_heros[i].crops[c];
                var cropTile = findTileByRowCol(crop.pos.row,crop.pos.col);

                //init les crops sur les tiles
                initCrop(crop,cropTile);
                hEnemy.addCrop(crop);
            }

            for(var b in sv_heros[i].buildings) {
                var building = sv_heros[i].buildings[b];
                var buildingTile = findTileByRowCol(building.pos.row, building.pos.col);

                initBuilding(building, buildingTile);
                hEnemy.addBuilding(building);
            }

            var hERow = sv_heros[i].pos.row;
            var hECol = sv_heros[i].pos.col;

            hEnemy.path.start = {
                x:  hERow,
                y:  hECol
            }

            hEnemy.path.stop = {
                x: null,
                y: null
            };

            hEnemy.path.steps[0] = tileMap[hERow][hECol];
            hEnemy.x = hEnemy.path.steps[0].x + (defaultTileWidth / 3);
            hEnemy.y = hEnemy.path.steps[0].y + (defaultTileHeight / 8);

            //On met à jour la liste des enemis en RAM
            enemyHeroes.push(hEnemy);

    //        console.log('enemy hero inited :');
    //        console.log(hEnemy);
        }
    }

    //charge les données du héros du joueur
    function loadPlayerData(sv_hero) {
        var hRow = sv_hero.pos.row;
        var hCol = sv_hero.pos.col;

        hero = new Hero(sv_hero._id, sv_hero.name, heroImg, sv_hero.gold, sv_hero.health);

        hero.path.start = {
            x: hRow,
            y: hCol
        };
        hero.path.stop = {
            x: null,
            y: null
        };

        hero.connected = true;

        hero.path.steps[0] = tileMap[hRow][hCol];
        hero.x = hero.path.steps[0].x + (defaultTileWidth / 3);
        hero.y = hero.path.steps[0].y + (defaultTileHeight / 8);

        camera.x -= (hero.x - (canvas.getWidth() / 2));
        camera.y -= (hero.y - (canvas.getHeight() / 2));

        //set tiles img en fonction du joueur
        loadPlayerTiles();
        loadPlayerCrops(sv_hero);
        loadPlayerBuildings(sv_hero);
        hero.computeStats();
        updHeroStats();
    //    console.log('my hero inited :');
    //    console.log(hero);
    }

    function loadPlayerTiles() {
        for (var row = 0, i = 1; row < grid.width; row++) {
            for (var col = 0; col < grid.height; col++, i++) {
                //hero.addTile se fait ici aussi
                tileMap[row][col].updateProperty();
            }
        }
    }

    function loadPlayerCrops(sv_hero) {
        for(var c in sv_hero.crops) {
            var crop = sv_hero.crops[c];
            var cropTile = findTileByRowCol(crop.pos.row,crop.pos.col);
            var complexCrop = initCrop(crop,cropTile);

            hero.addCrop(crop);
            hero.addComplexCrop(complexCrop);
            complexCrop.startTimer();
        }
    }

    function loadPlayerBuildings(sv_hero) {
        for(var b in sv_hero.buildings) {
            var building = sv_hero.buildings[b];
            var buildingTile = findTileByRowCol(building.pos.row, building.pos.col);

            initBuilding(building, buildingTile);
            hero.addBuilding(building);
            buildingTile.drawTile();
        }
    }

// --- ! SV EVENTS SECTION ! ---

    function newCrop(sv_crop) {
        var cropTile = findTileByRowCol(sv_crop.pos.row, sv_crop.pos.col);
            initCrop(sv_crop, cropTile);
            cropTile.drawTile();

        var cropHero = findHeroById(sv_crop.heroId);
            cropHero.addCrop(sv_crop);

//        console.log('new crop inited for hero '+cropHero.name);
    }

    function reloadCrop(sv_crop) {
        var cropTile = findTileByRowCol(sv_crop.pos.row, sv_crop.pos.col);
        var crop = findCropByRowCol(sv_crop.pos.row, sv_crop.pos.col);
            crop.curState = sv_crop.curState;

        if(crop.curState > crop.sprites.length + 2)
            crop.curSprite = c_decay;

        cropTile.drawTile();
    }

    function deleteCropAtPos(sv_cropPos) {
        var cropTile = findTileByRowCol(sv_cropPos.row, sv_cropPos.col);

        cropTile.crop = null;
        cropTile.canPass = 1;
        cropTile.drawTile();
    }

    function newBuilding(sv_building) {
        var buildingTile = findTileByRowCol(sv_building.pos.row, sv_building.pos.col);
        initBuilding(sv_building, buildingTile);
        buildingTile.drawTile();

        var cropHero = findHeroById(sv_building.heroId);
            cropHero.addBuilding(sv_building);

//        console.log('new crop inited for hero '+cropHero.name);
    }

    function updateCropsTimers() {
        if(hero.crops.length == 0) return;

        hero.updCropsTimers();
        cl_cropsTimers_update(hero.id, hero.crops);
    }

    //call at tile create from server
    function newTile(sv_tile) {}

    //call at tile update from server
    function reloadTile(sv_tile) {
        var curTile = findTileByRowCol(sv_tile.pos.row, sv_tile.pos.col);
        curTile.heroId = sv_tile.heroId;
        curTile.canPass = sv_tile.canPass;
        curTile.humidity = sv_tile.humidity;
        curTile.fertility = sv_tile.fertility;
        curTile.updateProperty();
        curTile.drawTile();
    }

// --- ! DRAW SECTION ! ---

    function draw() {
        c.clearRect (0, 0, canvas.width, canvas.height);

        //TILES
        for (var row = 0, count = 0; row < grid.width; row++) {
            for (var col = 0; col < grid.height; col++, count++) {

                var tilePositionX = (row - col) * defaultTileHeight;

                // Center the grid horizontally
                tilePositionX += (canvas.width / 2) - (defaultTileWidth / 2);
                var tilePositionY = (row + col) * (defaultTileHeight / 2);

                var curTile = tileMap[row][col];
                curTile.drawTile();
            }
        }    //console.log(count + ' tiles drawn');

        //HERO
        hero.drawHero();
        drawEnemies();
    //    console.log('calling draw()');
    }

    function drawRange(baseTile, range, clearScreen) {
        if(clearScreen)
            c.clearRect (0, 0, canvas.getWidth(), canvas.getHeight());

        var coordsBase = findRowCol(baseTile);

        for (var row = coordsBase.row - range; row <= coordsBase.row + range; row++) {
            for (var col = coordsBase.col - range; col <= coordsBase.col + range; col++) {
                if(row >= 0 && col >= 0 && row < grid.width && col < grid.height)
                    tileMap[row][col].drawTile();
            }

        }

        hero.drawHero();
        drawEnemies();
    //    console.log('calling drawRange()');
    }

    function drawEnemies() {
        for(var h in enemyHeroes) {
            enemyHeroes[h].drawHero(true);
        }
    }


// --- ! ASTAR SECTION ! ---

    function initAstarGrid(){
        for (var row = 0; row < grid.width; row++) {
            astarMap[row] = [];
            for (var col = 0; col < grid.height; col++) {
                if(tileMap[row][col].canPass == 0)
                    astarMap[row][col] = 1;
                else
                    astarMap[row][col] = 0;
            }
        }
    }

    function callPathFindingWorker(path, callback) {
        var w = new Worker(astar_path);
        initAstarGrid();

        w.postMessage({
            tileMap: astarMap,
            grid: {
                width: grid.width - 1,
                height: grid.height - 1
            },
            start: path.start,
            stop: path.stop
        });

        w.onmessage = callback;
    }

    function pathFindingWorkerResults(e) {
        var rsltLen = e.data.length;

        if (rsltLen > 0) {
            //si le héros est déjà en mouvement
            if(hero.moveTimer != false)
                return;
            else {
                hero.path.simpleSteps = [];
                for (var i = 1,j = rsltLen - 1; j >= 0; i++, j--) {
                    hero.path.steps[i] = {
                        row: e.data[j].x,
                        col: e.data[j].y
                    }
                    //steps sans tile @steps[0] pour send au srv
                    hero.path.simpleSteps[i] = {
                        row: e.data[j].x,
                        col: e.data[j].y
                    }
                }

                cl_move_event(hero.asSimpleObject(), hero.path.simpleSteps);
                hero.move();
            }
        }
    }

    function startAstar(rowDest, colDest) {
        hero.path.stop = {
            x: rowDest,
            y: colDest
        };

        callPathFindingWorker(hero.path, pathFindingWorkerResults);
    }

//Pop MSG on client
function gameMsg(msg) {
    ui_msg.innerHTML = msg;
    ui_msg.style.visibility = 'visible';

    setTimeout(function() {
        ui_msg.style.visibility = 'collapse';
    }, 4000);
}


//function fadeFromWhite(alphaVal) {
//    c.globalAlpha = alphaVal;
//
//    alphaVal = parseFloat(alphaVal) + 0.02;
//
//    if (alphaVal < 1.0) {
//        setTimeout(function() {
//            fadeFromWhite(alphaVal);
//        }, 30);
//    } else {
//        draw();
//    }
//}



